package pckg.positionlogger;

import java.util.Date;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;

public class ServiceGPS extends Service{
	
	protected double latitude;
    protected double longitude;
    protected double distance;
    protected double averageSpeed;	
    //Variables will be use in the time calculation.
    protected double totalTime;
    protected static long beginTime;
    protected static long actualTime;
    
    protected Location lastLocation; 
    private String packageName = "pckg.positionlogger";
    private String fileName = "positionlogger.gpx";
	
	LocationManager locationManager; //This class provides access to the system location services.
	LocationListener subscriber; //Used for receiving notifications from the LocationManager when the location has changed.
	
    //Control variables of the frequency of notification or new locations
	//To obtain notifications as frequently as possible, set both parameters to 0.
	private int interval = 0;  
	private int minDistance = 0;
	
	SDCard mySDCard;
	
	//Return the communication channel to the service, which clients can call on to the service.
	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	/*ON CREATE: called when the service is created*/	
	public void onCreate() { 
		super.onCreate();
		locationManager = (LocationManager)
        		getSystemService(Context.LOCATION_SERVICE);
        subscriber = new Subscriber();
        
        locationManager.requestLocationUpdates( //Registers the current activity to be notified periodically
    			LocationManager.GPS_PROVIDER,
        		//LocationManager.NETWORK_PROVIDER,
    			interval,
    			minDistance,
    			subscriber);
        
        mySDCard = new SDCard(packageName,fileName);
        beginTime=System.nanoTime(); //Get the initial time when the service start.
        distance = 0;
        averageSpeed = 0;
        
        String headInfo="<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n"+
    			"<gpx version=\"1.1\" creator=\"GPSBabel - http://www.gpsbabel.org\" " + "\n" +
    			"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "\n" +
    			"xmlns=\"http://www.topografix.com/GPX/1/1\" " + "\n" +
    			"xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">" + "\n" +
    			"<metadata><time>2009-04-20T19:43:14Z</time><bounds minlat=\"48.469001667\" minlon=\"9.495335000\" maxlat=\"48.530370000\" maxlon=\"9.547900000\"/>" + "\n" +
    			"</metadata><trk><trkseg>" + "\n\n";
    	
    	mySDCard.write(headInfo); //Writing the head of a .gpx file with all the information above.
    	
	}  
			//Provide the interface to the activity.
	private final PositionInterface.Stub mBinder = new PositionInterface.Stub() {
			public double getLatitude() throws RemoteException {
				return latitude;
			}
			public double getLongitude() throws RemoteException {
				return longitude;
			}
			public double getDistance() throws RemoteException {
				return distance;
			}
			public double getAverageSpeed() throws RemoteException {
				return averageSpeed;
			}
		};
	
	public void onDestroy(){
		String footInfo="</trkseg></trk></gpx>"; //Before stop the service, append the last Information in .gpx format to the file.
    	mySDCard.append(String.valueOf(footInfo));
    	
		locationManager.removeUpdates(subscriber); //Removes any current registration for location updates. 
		super.onDestroy();
	}
	
	public class Subscriber implements LocationListener{
	
						//Called when the location has changed.
		public void onLocationChanged(Location location) {
			latitude = location.getLatitude();
			longitude = location.getLongitude();
			if(lastLocation != null)
				distance = distance + location.distanceTo(lastLocation); //Distance in meters.
			
			lastLocation = location;

			totalTime=getTotalTime(System.nanoTime(),beginTime);
			
			if(totalTime != 0)
				averageSpeed=distance/totalTime;
			
			Date date = new Date(); 				//Appending the new values to the file, in .gpx format.
			mySDCard.append("<trkpt lat=\"" + String.valueOf(latitude)+ "\"");
	    	mySDCard.append(" lon=\"" + String.valueOf(longitude) + "\">\n");
	    	mySDCard.append("  <time>" + date.toString() + "</time>\n</trkpt>\n");	    
			
		}
		
		public long getTotalTime(long actualTime, long beginTime){			
			long totalTime;
			totalTime=(actualTime - beginTime)/1000000000; //Time in seconds.
			return totalTime;		
		}
		
		//Called when the provider is disabled by the user.
		public void onProviderDisabled(String provider) {
		}
		//Called when the provider is enabled by the user.
		public void onProviderEnabled(String provider) {
		}
		//Called when the provider status changes.
		public void onStatusChanged(String provider, int status, Bundle extras) {			
		}
		
	}

}
